/**
 * @file moderngamecontroller.h
 * @brief 现代化游戏控制器 - 整合所有系统
 */

#ifndef MODERNGAMECONTROLLER_H
#define MODERNGAMECONTROLLER_H

#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QTimer>
#include <QPushButton>
#include <QLabel>
#include <QSet>
#include <QDateTime>
#include <QJsonObject>
#include <QVariant>
#include "clientprediction.h"
#include "gamerenderer.h"
#include "asyncnetworkmanager.h"
#include "gamestateprocessor.h"
#include "renderthread.h"
#include "unifiedgamerenderer.h"

// 前向声明
class SnakeGameManager;

/**
 * @brief 现代化游戏控制器
 * 
 * 整合所有现代化游戏系统：
 * 1. 客户端预测 - 即时响应
 * 2. 高性能渲染 - 60FPS流畅
 * 3. 异步网络 - 低延迟通信
 * 4. 智能输入 - 优化控制体验
 */
class ModernGameController : public QWidget
{
    Q_OBJECT

public:
    explicit ModernGameController(QWidget *parent = nullptr);
    ~ModernGameController();

    /**
     * @brief 游戏配置
     */
    struct GameConfig {
        // 渲染配置
        int targetFPS = 60;
        bool enablePrediction = true;
        bool enableInterpolation = true;
        bool enableEffects = true;
        
        // 网络配置
        QString serverUrl = "ws://localhost:8080";
        bool enableCompression = true;
        int maxRetries = 3;
        int heartbeatInterval = 1000;
        
        // 输入配置
        int inputBufferSize = 10;
        float predictionConfidence = 0.8f;
        int maxPredictionSteps = 5;
    };

public slots:
    /**
     * @brief 启动游戏
     * @param config 游戏配置
     */
    void startGame(const GameConfig &config);

    /**
     * @brief 启动游戏（使用默认配置）
     */
    void startGame();

    /**
     * @brief 停止游戏
     */
    void stopGame();

    /**
     * @brief 暂停/恢复游戏
     */
    void pauseGame();
    void resumeGame();

    // connectToServer方法已删除，网络连接由专用网络线程负责

    /**
     * @brief 断开服务器连接
     */
    void disconnectFromServer();

    /**
     * @brief 设置WebSocket管理器
     * @param manager WebSocket管理器
     */
    void setWebSocketManager(SnakeGameManager *manager);

signals:
    /**
     * @brief 游戏状态变化
     * @param state 游戏状态 ("starting", "running", "paused", "stopped")
     */
    void gameStateChanged(const QString &state);

    /**
     * @brief 性能统计
     * @param fps 帧率
     * @param latency 网络延迟
     * @param predictionAccuracy 预测准确率
     */
    void performanceStats(int fps, int latency, float predictionAccuracy);

    /**
     * @brief 方向改变请求信号（发送到网络线程）
     * @param direction 方向 (0=UP, 1=DOWN, 2=LEFT, 3=RIGHT)
     */
    void directionChangeRequested(int direction);

    /**
     * @brief 游戏事件
     * @param event 事件类型
     * @param data 事件数据
     */
    void gameEvent(const QString &event, const QVariant &data);

    /**
     * @brief 游戏错误信号
     * @param error 错误信息
     */
    void gameError(const QString &error);

    /**
     * @brief 返回大厅信号
     */
    void backToLobby();

protected:
    /**
     * @brief 键盘事件处理
     */
    void keyPressEvent(QKeyEvent *event) override;
    void keyReleaseEvent(QKeyEvent *event) override;

    /**
     * @brief 焦点事件处理
     */
    void focusInEvent(QFocusEvent *event) override;
    void focusOutEvent(QFocusEvent *event) override;

    /**
     * @brief 全局事件过滤（兜底捕获键盘事件）
     */
    bool eventFilter(QObject *obj, QEvent *event) override;

    /**
     * @brief 显隐事件：在显示时安装过滤器，隐藏时卸载
     */
    void showEvent(QShowEvent *event) override;
    void hideEvent(QHideEvent *event) override;

private slots:
    /**
     * @brief 客户端预测状态更新
     * @param predictedState 预测状态
     */
    void onPredictedStateUpdated(const ClientPrediction::PredictedState &predictedState);

    /**
     * @brief 需要发送输入到服务器
     * @param direction 方向
     * @param sequenceNumber 序列号
     */
    void onSendInputToServer(int direction, int sequenceNumber);

    /**
     * @brief 网络连接状态变化
     * @param connected 是否已连接
     */
    void onConnectionStateChanged(bool connected);

    /**
     * @brief 接收到游戏状态
     * @param gameState 游戏状态
     * @param serverTimestamp 服务器时间戳
     */
    void onGameStateReceived(const QJsonObject &gameState, qint64 serverTimestamp);

    /**
     * @brief 输入确认
     * @param sequenceNumber 序列号
     * @param serverTimestamp 服务器时间戳
     */
    void onInputAcknowledged(int sequenceNumber, qint64 serverTimestamp);

    /**
     * @brief 网络统计更新
     * @param stats 网络统计
     */
    void onNetworkStatsUpdated(const AsyncNetworkManager::NetworkStats &stats);

    /**
     * @brief 渲染性能更新
     * @param fps 帧率
     * @param frameTime 帧时间
     */
    void onFrameRateUpdated(int fps, float frameTime);

    /**
     * @brief 预测错误
     * @param errorMagnitude 错误程度
     */
    void onPredictionError(float errorMagnitude);

    /**
     * @brief 食物被吃处理
     * @param foodPosition 被吃的食物位置
     */
    void onFoodEaten(const QPoint &foodPosition);

    /**
     * @brief WebSocket游戏状态更新处理
     */
    void onWebSocketGameStateUpdated(const QJsonObject &gameState);

    /**
     * @brief 玩家死亡处理
     */
    void onPlayerDied();

    /**
     * @brief 房间创建成功处理
     */
    void onRoomCreated(const QString &roomId);

    /**
     * @brief 房间加入成功处理
     */
    void onRoomJoined(const QString &roomId);



    /**
     * @brief 性能监控定时器
     */
    void onPerformanceTimer();

    /**
     * @brief 游戏循环定时器槽
     */
    void onGameLoop();

    /**
     * @brief 统一渲染器信号处理
     */
    void onRenderingError(const QString &error);

    /**
     * @brief 渲染数据更新处理（同步 GameRenderer 目标状态）
     */
    void onRenderDataUpdated(const RenderReadyGameData &data);

public:
    /**
     * @brief 获取统一渲染器
     * @return 统一渲染器指针
     */
    UnifiedGameRenderer* getUnifiedRenderer() const { return m_unifiedRenderer; }

private:
    /**
     * @brief 初始化所有系统
     */
    void initializeSystems();

    /**
     * @brief 设置系统连接
     */
    void setupConnections();

    /**
     * @brief 初始化游戏数据
     */
    void initializeGameData();

    /**
     * @brief 创建单人游戏房间
     */
    void createSinglePlayerRoom();

    /**
     * @brief 在房间中开始游戏
     */
    void startGameInRoom();

    // 旧的多线程方法已移除，功能已集成到UnifiedGameRenderer中

    /**
     * @brief 新帧就绪处理
     */
    void onFrameReady(const QPixmap &frame);

    /**
     * @brief FPS更新处理
     */
    void onFPSUpdated(int fps);

    // 旧的统计处理方法已移除，现在使用UnifiedGameRenderer的性能统计

    /**
     * @brief 降级模式的游戏状态处理
     */
    void processFallbackGameState(const QJsonObject &gameState);

    /**
     * @brief 监控线程健康状态
     */
    void monitorThreadHealth();

    /**
     * @brief 尝试恢复失败的线程
     */
    void attemptThreadRecovery();

    /**
     * @brief 异步发送方向到服务器
     */
    void sendDirectionToServer(int direction);

    /**
     * @brief 监控内存使用情况
     */
    void monitorMemoryUsage();

    /**
     * @brief 清理内存缓存
     */
    void cleanupMemoryCache();

    /**
     * @brief 生成新食物
     */
    void generateNewFood(const QPoint &eatenFoodPos);

    /**
     * @brief 处理用户输入
     * @param direction 方向
     */
    void handleUserInput(int direction);

    /**
     * @brief 解析服务器游戏状态
     * @param gameState JSON游戏状态
     * @return 解析后的状态
     */
    ClientPrediction::PredictedState parseServerGameState(const QJsonObject &gameState);

    /**
     * @brief 更新性能统计
     */
    void updatePerformanceStats();

    /**
     * @brief 优化系统性能
     */
    void optimizePerformance();

private:
    // === 核心系统 ===
    ClientPrediction *m_clientPrediction;      // 客户端预测系统
    GameRenderer *m_gameRenderer;              // 游戏渲染器
    AsyncNetworkManager *m_networkManager;     // 网络管理器
    SnakeGameManager *m_webSocketManager;          // WebSocket管理器（外部提供）

    // === 统一渲染系统 ===
    UnifiedGameRenderer *m_unifiedRenderer;    // 统一游戏渲染器（新架构）

    // === 旧多线程组件已移除，功能已集成到UnifiedGameRenderer中 ===
    
    // === 布局和UI ===
    QVBoxLayout *m_layout;                     // 主布局
    QHBoxLayout *m_controlLayout;              // 控制按钮布局
    QPushButton *m_pauseButton;                // 暂停/恢复按钮
    QPushButton *m_restartButton;              // 重新开始按钮
    QPushButton *m_backButton;                 // 返回大厅按钮
    QLabel *m_scoreLabel;                      // 分数标签
    QLabel *m_fpsLabel;                        // FPS标签
    
    // === 游戏状态 ===
    GameConfig m_config;                       // 游戏配置
    QString m_currentGameState;                // 当前游戏状态
    bool m_isGameRunning;                      // 游戏是否运行中
    bool m_isGamePaused;                       // 游戏是否暂停
    bool m_isConnected;                        // 是否已连接服务器
    
    // === 性能监控 ===
    QTimer *m_performanceTimer;                // 性能监控定时器

    // === 游戏逻辑 ===
    QTimer *m_gameLoopTimer;                   // 游戏循环定时器
    int m_currentDirection;                    // 当前移动方向
    int m_gameSpeed;                           // 游戏速度(ms)
    QList<QPoint> m_currentFoods;              // 当前食物位置
    int m_currentScore;                        // 当前分数
    QString m_currentRoomId;                   // 当前房间ID
    QString m_currentPlayerId;                 // 当前玩家ID

    // === 多线程同步 ===
    QMutex m_renderMutex;                      // 渲染互斥锁
    bool m_threadsRunning;                     // 线程是否运行中
    bool m_fallbackMode;                       // 是否处于降级模式
    QTimer *m_threadMonitorTimer;              // 线程监控定时器
    int m_threadFailureCount;                  // 线程失败计数

    // === 性能和内存监控 ===
    QTimer *m_memoryMonitorTimer;              // 内存监控定时器
    qint64 m_lastMemoryCheck;                  // 上次内存检查时间
    static const qint64 MAX_MEMORY_MB = 512;   // 最大内存使用限制(MB)
    struct PerformanceData {
        int currentFPS;
        int networkLatency;
        float predictionAccuracy;
        float averageFrameTime;
        int droppedFrames;
        qint64 lastUpdateTime;
    } m_performance;

    // UI实际帧率（每秒统计一次）
    std::atomic<int> m_uiFps{0};
    int m_uiFrameCount{0};
    qint64 m_uiLastFpsTime{0};

    // === 输入管理 ===
    QSet<int> m_pressedKeys;                   // 当前按下的键
    qint64 m_lastInputTime;                    // 最后输入时间
    int m_inputSequence;                       // 输入序列号
    QMap<int, qint64> m_inputSendTimes;        // 输入发送时间记录（序列号 -> 时间戳）

    // === 调试和统计 ===
    int m_totalInputs;                         // 总输入次数
    int m_successfulPredictions;               // 成功预测次数
    int m_failedPredictions;                   // 失败预测次数
    QList<float> m_latencyHistory;             // 延迟历史

    // === 渲染管线控制 ===
    bool m_useUnifiedPipeline;                 // 是否使用统一渲染管线
    bool m_hasFirstFrame;                      // 是否已收到首帧
};

#endif // MODERNGAMECONTROLLER_H
